package com.stone.serverless.web;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import com.stone.serverless.sdk.loader.ModuleClassLoader;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Description: TODO
 * @Author: MECHREVO
 * @Date: 2022/1/25 16:25
 * @Version: 1.0.0
 */
@Component
public class ClassLoaderBeanNameMappingInfoHandlerMapping extends BeanNameUrlHandlerMapping {

    private  Map<String, Map<String, List<Object>>> componentNameMap;


    public void setComponentNameMap(Map<String, Map<String, List<Object>>> componentNameMap) {
        this.componentNameMap = componentNameMap;
    }

    @Override
    protected Object lookupHandler(String lookupPath, HttpServletRequest request) throws Exception {
        String requestURI = request.getRequestURI();
        String[] split = requestURI.split("/");
        List<String> list = new ArrayList<>();
        for (String s : split) {
            if (CharSequenceUtil.isNotBlank(s)) {
                list.add(s);
            }
        }
        if (list.size() != 4) {
            return null;
        }
        if (MapUtil.isEmpty(componentNameMap)) {
            return null;
        }
        Map<String, List<Object>> objectMap = componentNameMap.get(list.get(0));
        if (MapUtil.isEmpty(objectMap)) {
            return null;
        }
        List<Object> listObj = objectMap.get(list.get(1));
        if (CollUtil.isEmpty(listObj)) {
            return null;
        }
        Object o = listObj.get(0);
        ClassLoader classLoader = o.getClass().getClassLoader();
        Class<?> superclass = classLoader.getClass().getSuperclass();
        if (null == superclass) {
            return null;
        }
        Class<?>[] interfaces = superclass.getInterfaces();
        if (null == interfaces || interfaces.length == 0) {
            return null;
        }

        if (interfaces[0].getName().equals(ModuleClassLoader.class.getName())) {
            Object bean = ReflectUtil.invoke(classLoader, "getInstance", list.get(2));
            //return bean;

            Method method = Arrays.stream(ReflectUtil.getMethods(bean.getClass(), v -> v.getName().equals(list.get(3)))).findFirst().orElse(null);

            HandlerMethod handlerMethod = new HandlerMethod(bean, method);
            return handlerMethod;
        }

        return null;

    }
}
